#ifndef DockAreaTabBarH
#define DockAreaTabBarH
/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/


//============================================================================
/// \file   DockAreaTabBar.h
/// \author Uwe Kindler
/// \date   24.08.2018
/// \brief  Declaration of CDockAreaTabBar class
//============================================================================

//============================================================================
//                                   INCLUDES
//============================================================================
#include <QScrollArea>
#include "ads_globals.h"

namespace ads
{
    class CDockAreaWidget;
    class CDockWidgetTab;
    struct DockAreaTabBarPrivate;
    class CDockAreaTitleBar;
    class CFloatingDockContainer;
    class IFloatingWidget;

    /**
     * 自定义的选项卡栏实现，用于显示在停靠区窗口的顶部。
     * 该选项卡栏显示包含的停靠窗口的选项卡小部件。
     * 我们不能在这里使用QTabBar，因为它会执行很多花哨的动画，
     * 如果在动画尚未完成时移除选项卡，应用程序会崩溃。
     * 而且，如果用户将一个停靠窗口从选项卡组中拖出，我们需要移除一个选项卡。
     */
    class ADS_EXPORT CDockAreaTabBar : public QScrollArea
    {
        Q_OBJECT
    private:
        DockAreaTabBarPrivate* d; ///< 私有数据 (pimpl)
        friend struct DockAreaTabBarPrivate;
        friend class CDockAreaTitleBar;

    private Q_SLOTS:
        void onTabClicked();
        void onTabCloseRequested();
        void onCloseOtherTabsRequested();
        void onTabWidgetMoved(const QPoint& GlobalPos);

    protected:
        virtual void wheelEvent(QWheelEvent* Event) override;

    public:
        using Super = QScrollArea;

        /**
         * 默认构造函数
         */
        CDockAreaTabBar(CDockAreaWidget* parent);

        /**
         * 虚析构函数
         */
        virtual ~CDockAreaTabBar();

        /**
         * 在给定位置插入给定的停靠窗口选项卡。
         * 在小于或等于当前索引的位置插入新的选项卡将增加当前索引，但保留当前选项卡。
         */
        void insertTab(int Index, CDockWidgetTab* Tab);

        /**
         * 从选项卡栏中移除给定的DockWidgetTab
         */
        void removeTab(CDockWidgetTab* Tab);

        /**
         * 返回此选项卡栏中的选项卡数量
         */
        int count() const;

        /**
         * 返回当前索引，如果没有选中的选项卡，则返回-1
         */
        int currentIndex() const;

        /**
         * 返回当前选项卡，如果没有选中的选项卡，则返回nullptr。
         */
        CDockWidgetTab* currentTab() const;

        /**
         * 返回给定索引的选项卡
         */
        CDockWidgetTab* tab(int Index) const;

        /**
         * 返回给定位置的选项卡。
         * 如果位置在第一个选项卡的左侧，则返回-1；
         * 如果位置在最后一个选项卡的右侧，则返回count()；
         * 如果位置无效，则返回-2。
         */
        int tabAt(const QPoint& Pos) const;

        /**
         * 返回给定鼠标光标位置的选项卡插入索引
         */
        int tabInsertIndexAt(const QPoint& Pos) const;

        /**
         * 过滤选项卡小部件的事件
         */
        virtual bool eventFilter(QObject *watched, QEvent *event) override;

        /**
         * 此函数返回true，如果选项卡是打开的，即对用户可见。
         * 如果函数返回false，则选项卡是关闭的。
         */
        bool isTabOpen(int Index) const;

        /**
         * 覆盖QScrollArea的minimumSizeHint()函数。
         * minimumSizeHint()比sizeHint()更大，因为即使滚动条不可见，minimumSizeHint()中也会保留所需的空间。
         * 此覆盖函数简单地返回sizeHint()。
         */
        virtual QSize minimumSizeHint() const override;

        /**
         * 此函数提供的sizeHint与内部视口的高度匹配。
         */
        virtual QSize sizeHint() const override;

    public Q_SLOTS:
        /**
         * 此属性设置选项卡栏的可见选项卡的索引
         */
        void setCurrentIndex(int Index);

        /**
         * 此函数将关闭给定索引处的选项卡。
         * 关闭选项卡意味着将隐藏选项卡，而不是移除它。
         */
        void closeTab(int Index);

    Q_SIGNALS:
        /**
         * 当选项卡栏的当前选项卡即将更改时，发出此信号。
         * 新的当前选项卡具有给定的索引，如果没有新的当前选项卡，则为-1。
         */
        void currentChanging(int Index);

        /**
         * 当选项卡栏的当前选项卡更改时，发出此信号。
         * 新的当前选项卡具有给定的索引，如果没有新的当前选项卡，则为-1。
         */
        void currentChanged(int Index);

        /**
         * 当用户单击选项卡时，发出此信号。
         */
        void tabBarClicked(int index);

        /**
         * 当选项卡上的关闭按钮被单击时，发出此信号。
         * 索引是应该关闭的选项卡的索引。
         */
        void tabCloseRequested(int index);

        /**
         * 当选项卡关闭时，发出此信号。
         */
        void tabClosed(int index);

        /**
         * 当选项卡打开时，发出此信号。
         * 如果选项卡已经可见，则认为选项卡已打开。
         */
        void tabOpened(int index);

        /**
         * 当选项卡移动时，发出此信号。
         * from参数是移动的选项卡的起始位置的索引，
         * to参数是移动的选项卡的目标位置的索引。
         */
        void tabMoved(int from, int to);

        /**
         * 当选项卡被移除之前，发出此信号。
         * index参数是要移除的选项卡的索引。
         */
        void removingTab(int index);

        /**
         * 当插入选项卡时，发出此信号。
         * index参数是插入的选项卡的索引。
         */
        void tabInserted(int index);

        /**
         * 当选项卡标题的省略状态发生变化时，发出此信号。
         * elided参数表示标题是否被省略。
         */
        void elidedChanged(bool elided);
    }; // class CDockAreaTabBar
} // namespace ads

